home *** CD-ROM | disk | FTP | other *** search
- #include "Painterly.h"
-
- /* Painterly Globals */
- extern MenuHandle gPaintMenuHandles[]; /* The menus we add */
- extern DocumentRecord gSrcDoc, gDstDoc; /* The doc records */
- extern CWindowPtr gSrcWindPtr, gDstWindPtr; /* the windows */
- extern Handle gCurrentBrushHandle; /* handle to the current Brush code */
- extern short gCurrentBrushNum; /* the current Brush menu item */
- extern BrushParams gBrushStuff; /* the parameter structure for brush calls */
- extern Point gNextPoint; /* the next point touched in ordered strokes */
- extern short gOrderedIncrement;
- extern Boolean gPaintingNow, gRandomStrokes;
- extern THPrint gPrintRecHandle;
- extern RGBColor gBGColor;
- extern short gDocTitleHeight;
-
- /* These globals are used only by the pict spooling procedures */
- OSErr gPictError;
- long gPictSize;
- PicHandle gPictHandle;
- short gPictFileRef;
-
- /* Called when the user selects a filter from the Filter Menu */
- void DoFilterMenu(short item)
- {
- short rslt;
- Str255 filterName;
- Handle theFilter;
- WindowPtr wind;
-
- /* Do nothing if the front window isn't ours */
- wind = FrontWindow();
- if(IsAppWindow(wind) == false)
- return;
-
- /* Get the name of the filter */
- GetItem(gPaintMenuHandles[kFilterMenu], item, filterName);
-
- /* Load the filter */
- theFilter = GetNamedResource('FLTR', filterName);
- if(ResError() == noErr && theFilter != nil)
- {
- DocumentPeek doc;
-
- /* Get the document */
- doc = (DocumentPeek)wind;
- if(doc->world != nil)
- {
- /* Allow an undo */
- SetUpForUndo(wind);
- /* rslt is ignored here: presumably the filter told the user what was wrong */
- rslt = CallFilter(doc->world, theFilter);
- SetPort(wind);
- InvalRect(&wind->portRect);
- }
- ReleaseResource(theFilter);
- }
- else
- DoErrorAlert(kNoFilterStr, 0);
- }
-
- void DoBrushMenu(short item)
- {
- switch(item)
- {
- case iPenSize:
- PenDlog();
- break;
-
- case iConfigureBrush:
- CallBrush(kConfigure, &gBrushStuff, gCurrentBrushHandle);
- break;
-
- default: /* A brush selected */
- {
- short rslt;
-
- /* if the selected brush is the same as the current one, do nothing */
- if(item == gCurrentBrushNum)
- break;
-
- /* Set up the new brush */
- rslt = SetCurrentBrush(item);
- if(rslt == noErr)
- {
- long flags;
-
- /* We switched successfully. If the Configure item is enabled,
- configure the brush. */
- flags = (**gPaintMenuHandles[kBrushMenu]).enableFlags;
- if( flags & (1L << iConfigureBrush) )
- {
- /* The item is enabled, so go ahead and configure */
- CallBrush(kConfigure, &gBrushStuff, gCurrentBrushHandle);
- }
- }
- break;
- }
- }
- }
-
- void DoPaintMenu(short item)
- {
- CGrafPtr oldport;
- GDHandle olddev;
- Str255 itemText;
-
- switch(item)
- {
- case iSetup:
- AutoPaintSetupDlog();
- break;
-
- case iStartPainting: /* Go/Stop */
- if(gPaintingNow == true)
- {
- /* Stopping painting... */
- SetItem(gPaintMenuHandles[kAutoPaintMenu], iStartPainting,
- TheStr(itemText, kStartPainting));
- gPaintingNow = false;
-
- /* Reset the point for ordered strokes */
- gNextPoint.h = 0;
- gNextPoint.v = 0;
- }
- else
- {
- /* Starting painting, allow undo */
- SetUpForUndo(gDstWindPtr);
- SetItem(gPaintMenuHandles[kAutoPaintMenu], iStartPainting,
- TheStr(itemText, kStopPainting));
- gPaintingNow = true;
- }
- break;
- }
- }
-
- /* This routine runs the "Save Changes" dialogs, if needed, and responds appropriately.
- It returns true if the caller should proceed, or false if the user cancels the save. */
- Boolean SaveCurrentDocs(void)
- {
- short rslt;
- Boolean quit = true;
-
- /* First make sure there is a document open. If not, just return true */
- if(((WindowPeek)&gSrcDoc)->visible != true)
- return quit;
-
- /* If the Src window needs saving, do the dialog */
- if(gSrcDoc.dirty)
- {
- /* Bring the window to the front, and process activate and update events */
- SelectWindow(gSrcWindPtr);
- DoActivateUpdate();
- rslt = SaveChangesDlog();
- switch(rslt)
- {
- case 1: /* Save */
- quit = !AppSave(); /* AppSave() returns true only if the user
- canceled the StandardFile dialog, or if
- there was an error, in which case we should
- cancel */
- break;
-
- case 4: /* No save */
- quit = true;
- break;
-
- case 2: /* Cancel */
- quit = false;
- break;
- }
- }
-
- /* Keep going? */
- if(quit)
- {
- /* If the Dst window needs saving, do the dialog */
- if(gDstDoc.dirty)
- {
- /* Bring the window to the front, and process activate and update events */
- SelectWindow(gDstWindPtr);
- DoActivateUpdate();
- rslt = SaveChangesDlog();
- switch(rslt)
- {
- case 1: /* Save */
- quit = !AppSave(); /* AppSave() returns true only if the user
- canceled the StandardFile dialog, or if
- there was an error, in which case we should
- cancel */
- break;
-
- case 4: /* No save */
- quit = true;
- break;
-
- case 2: /* Cancel */
- quit = false;
- break;
- }
- }
- }
- return quit;
- }
-
- /* This routine positions and sizes the windows (assumed hidden) appropriately
- for a "new" document and then shows them. The GWorlds are assumed to be already
- set up. */
- void SetUpAndShowWindows(void)
- {
- Rect deviceRect, docRect;
- GDHandle theDevice;
- short stagger = 32, horSize, verSize, wTop, wLeft;
-
- /* Set up a rect on the deepest device that is inset 4 pixels from the edges.
- Note that if it is the Main device we have to take into account the menu bar. */
- deviceRect = (**GetGrayRgn()).rgnBBox; /* Get rect of entire desktop */
- theDevice = GetMaxDevice(&deviceRect); /* Get the deepest device */
- deviceRect = (*theDevice)->gdRect; /* Get its rect */
- InsetRect(&deviceRect, 4, 4); /* Leave a 4 pixel border on the edges */
- if(theDevice == GetMainDevice()) /* Add the menu bar height if the main device */
- deviceRect.top += GetMBarHeight();
-
- docRect = gSrcDoc.world->portRect; /* top left is always 0, 0 */
-
- /* OK, first the source window. Need to add the height of the title bar
- to the vertical coordinate */
- wLeft = deviceRect.left;
- wTop = deviceRect.top + gDocTitleHeight;
- MoveWindow(gSrcWindPtr, wLeft, wTop, false);
-
- /* Now calculate a good size for the window. We'd like to make it the full size of the
- GWorld (plus scroll bars), but if it would then hang over the edges of the screen,
- we make it smaller. */
- horSize = docRect.right + kScrollAdjust;
- if(wLeft + horSize > deviceRect.right) /* hangs off the right */
- horSize = deviceRect.right - wLeft;
- verSize = docRect.bottom + kScrollAdjust;
- if(wTop + verSize > deviceRect.bottom) /* hangs off the bottom */
- verSize = deviceRect.bottom - wTop;
-
- /* Size it, and reset the clip */
- SizeWindow(gSrcWindPtr, horSize, verSize, false);
- SetPort(gSrcWindPtr);
- ClipRect(&gSrcWindPtr->portRect);
-
- /* Now the destination window */
- wTop += stagger;
- wLeft += stagger;
- MoveWindow(gDstWindPtr, wLeft, wTop, false);
-
- /* Use the same sizes as for the source, unless it hangs off the edge */
- if(wLeft + horSize > deviceRect.right) /* hangs off the right */
- horSize = deviceRect.right - wLeft;
- if(wTop + verSize > deviceRect.bottom) /* hangs off the bottom */
- verSize = deviceRect.bottom - wTop;
-
- /* Size it, and reset the clip */
- SizeWindow(gDstWindPtr, horSize, verSize, false);
- SetPort(gDstWindPtr);
- ClipRect(&gDstWindPtr->portRect);
-
- /* Make sure the scrollbars are presentable */
- AdjustScrollbars(gSrcWindPtr, true);
- AdjustScrollbars(gDstWindPtr, true);
-
- /* OK, we're ready. Show the windows, putting the source in front */
- ShowWindow(gSrcWindPtr);
- ShowWindow(gDstWindPtr);
-
- /* Enable the appropriate menus */
- EnableItem(gPaintMenuHandles[kFilterMenu], 0);
- EnableItem(gPaintMenuHandles[kBrushMenu], 0);
- EnableItem(gPaintMenuHandles[kAutoPaintMenu], 0);
- DrawMenuBar();
- }
-
-
- /* Opens the file indicated by fileSpec, reads the pict into the GWorlds,
- and creates a new document, showing the windows. This routine is ugly as
- hell and WAY too big. Sorry about that. Would you believe an exercise for the
- reader? Didn't think so. I do think it's a pretty safe rouine, just real ugly...*/
- OSErr ReadPICTFileToNewWorlds(FSSpec *fileSpec)
- {
- OSErr err;
- long readSize, pictSize;
- short refNum;
- CQDProcs *oldProcs, newProcs;
- Picture thePict;
- CursHandle Curs;
-
- /* Open the file, get the size of the pict, and read in just the Picture
- structure (picSize and picFrame) so we can get the size of the GWorlds
- we need, */
- err = FSpOpenDF(fileSpec, fsWrPerm, &refNum);
- if(err == noErr)
- {
- /* Get the size of the pict in the file */
- err = GetEOF(refNum, &pictSize);
- if(err == noErr)
- {
- /* subtract standard PICT header length */
- pictSize -= kPICTHeaderSize;
- /* Set the file marker to the start of the PICT data */
- err = SetFPos(refNum, fsFromStart, (long)kPICTHeaderSize);
- if(err == noErr)
- {
- readSize = sizeof(Picture);
- err = FSRead(refNum, &readSize, &thePict);
- }
- }
-
- /* Now build the GWorlds */
- if(err == noErr)
- {
- /* Try to Build the new GWorlds */
- if(InitGlobalGWorlds(&thePict.picFrame) == true)
- {
- /* Set the cursor to a watch, this may take a while */
- Curs = GetCursor(watchCursor);
- if(Curs != nil)
- SetCursor(*Curs);
-
- /* Allocate the pict handle, installing spooling if we're low on memory.
- then call DrawPictOff to draw the picture offscreen. */
-
- /* Try the quick and dirty method, allocating the pict in Temp Mem
- or app mem */
- gPictHandle = (PicHandle)TempNewHandle(pictSize, &err);
- if(gPictHandle == nil) /* Try for app mem, and reset error */
- {
- err = noErr;
- gPictHandle = (PicHandle)NewHandle(pictSize);
- }
-
- /* If it worked, we got off easy. Read the pict in and draw it. */
- if(gPictHandle != nil)
- {
- /* Set position back to just after the file header */
- err = SetFPos(refNum, fsFromStart, (long)kPICTHeaderSize);
- if(err == noErr)
- {
- err = FSRead(refNum, &pictSize, *gPictHandle);
- if(err == noErr)
- {
- DrawPictOff(gSrcDoc.world, gPictHandle);
- }
- }
- DisposHandle(gPictHandle);
- gPictHandle = nil;
- }
- else
- {
- /* No such luck, need to spool in the pict. First allocate a little
- handle to get it started */
- gPictHandle = (PicHandle)(NewHandleClear(sizeof(Picture)));
- if(gPictHandle != nil)
- {
- /* Copy the Picture data we read in earlier. the file position is
- still at the start of the pict data */
- **gPictHandle = thePict;
-
- /* save old grafProcs */
- oldProcs = gSrcDoc.world->grafProcs;
-
- /* Initialize the new procs with default values, then insert our
- custom getPic Proc and install in the world */
- SetStdCProcs(&newProcs);
- newProcs.getPicProc = PictReader;
- gSrcDoc.world->grafProcs = &newProcs;
-
- /* Now set up the globals that PictReader needs */
- gPictError = noErr;
- gPictFileRef = refNum;
-
- /* Finally, draw the Picture in the world and throw it away */
- DrawPictOff(gSrcDoc.world, gPictHandle);
- DisposHandle(gPictHandle);
- gPictHandle = nil;
-
- /* Restore old grafProcs */
- gSrcDoc.world->grafProcs = oldProcs;
-
- /* if there was a read error, post it */
- err = gPictError;
- }
- else
- err = memFullErr;
- }
- }
- else
- {
- /* Couldn't make the new GWorlds */
- err = memFullErr;
- }
- }
-
- if(err == noErr)
- {
- Str255 newTitle, fileName;
-
- /* The picture is drawn in the world and order is restored. Now we need to
- do the bookkeeping and make a real document to show the user */
-
- /* First reset the BrushParams, so brushes don't get confused. */
- gBrushStuff.pt.h = 0;
- gBrushStuff.pt.v = 0;
- gBrushStuff.rect = thePict.picFrame;
- gBrushStuff.theSource = gSrcDoc.world;
- gBrushStuff.theDestination = gDstDoc.world;
-
- /* Reset Src and Dst file names to empty, so Save does a SaveAs */
- *gSrcDoc.fileSpec.name = 0;
- *gDstDoc.fileSpec.name = 0;
-
- /* Rename the window to match the file name */
- SetWTitle(gSrcWindPtr, fileSpec->name);
-
- /* Cheater conversion from Str63 to Str255 */
- GetWTitle(gSrcWindPtr, fileName);
- /* If the strings aren't too long, rename the dst to
- "<filename>Art?", otherwise just "Art?" */
- if(PStrCat(fileName, TheStr(newTitle, kArtStr), true) != nil)
- SetWTitle(gDstWindPtr, fileName);
- else
- SetWTitle(gDstWindPtr, TheStr(newTitle, kArtStr));
-
- /* Set the dirty flags */
- gSrcDoc.dirty = false; /* no need to save unless it changes */
- gDstDoc.dirty = false; /* assume no one wants to save an empty picture */
-
- /* Finally, reset and show the windows */
- SetUpAndShowWindows();
- }
-
- /* Close the file and restore the cursor */
- FSClose(refNum);
- InitCursor();
- }
- return err;
- }
-
-
-
-
-
-
- /* Man, it's a pain when people want to replace an existing file. We go through this
- every time someone saves a document. Sheesh! */
- OSErr WorldToExistingFile(FSSpec *fileSpec, GWorldPtr world)
- {
- OSErr err;
- long tempLong;
- short tempRefNum;
- Str255 tempName;
- FSSpec tempSpec;
- FInfo finderStuff;
-
- /* Make a unique file name */
- GetDateTime(&tempLong);
- NumToString(tempLong, tempName);
-
- /* locate the temporary items folder */
- err = FindFolder(fileSpec->vRefNum, kTemporaryFolderType, kCreateFolder,
- &tempRefNum, &tempLong);
- if(err == noErr)
- {
- /* Make a new FSSpec */
- err = FSMakeFSSpec(tempRefNum, tempLong, tempName, &tempSpec);
- if(err == noErr || err == fnfErr)
- {
- /* Create the temp file */
- err = FSpCreate(&tempSpec, 'trsh', 'trsh', smSystemScript);
- if(err == noErr)
- {
- /* OK, we have a new temp file, let's write to it */
- err = WriteWorldToPICTFile(&tempSpec, world);
- if(err == noErr)
- {
- /* Lookin' good. Now, we need to exchange the data, set the Finder
- Info of the old (now new) file, and delete the temp file */
- err = FSpExchangeFiles(&tempSpec, fileSpec);
- if(err == noErr)
- {
- /* First get the existing finder Info */
- err = FSpGetFInfo(fileSpec, &finderStuff);
- if(err == noErr)
- {
- /* then set it to our type and creator */
- finderStuff.fdType = 'PICT';
- finderStuff.fdCreator = 'ART?';
- /* Don't care about this error: we did our best, by golly */
- FSpSetFInfo(fileSpec, &finderStuff);
- }
- }
- }
- /* We successfully created the temp file, so now delete it,
- whatever else may have happened. If we can't, there's
- nothing we can do about it, so this error is ignored */
- FSpDelete(&tempSpec);
- }
- }
- }
- return err;
- }
-
- /* It's much easier just to creat a new file */
- OSErr WorldToNewFile(FSSpec *fileSpec, GWorldPtr world)
- {
- OSErr err;
-
- err = FSpCreate(fileSpec, 'ART?', 'PICT', smSystemScript);
- if(err == noErr)
- {
- err = WriteWorldToPICTFile(fileSpec, world);
- /* If there were errors, delete the file */
- if(err != noErr)
- FSpDelete(fileSpec);
- }
- return err;
- }
-
- /* Opens the file indicated by fileSpec, spools out the GWorld as a pict, and closes the
- file.
- This routine is ugly as
- hell and WAY too big. Sorry about that. Would you believe an exercise for the
- reader? Didn't think so. I do think it's a pretty safe rouine, just real ugly...*/
- OSErr WriteWorldToPICTFile(FSSpec *fileSpec, GWorldPtr world)
- {
- CGrafPtr oldport;
- GDHandle olddev;
- OSErr err;
- long writeSize;
- short refNum;
- Ptr zeros;
- CQDProcs *oldProcs, newProcs;
-
- GetGWorld(&oldport, &olddev);
-
- /* First open the file */
- err = FSpOpenDF(fileSpec, fsWrPerm, &refNum);
- if(err == noErr)
- {
- /* Write out zeros for header bytes */
- writeSize = kPICTHeaderSize;
- zeros = NewPtrClear(writeSize);
- if(zeros != nil)
- {
- err = FSWrite(refNum, &writeSize, zeros);
- }
- else
- {
- /* Bummer, memory's really tight, do it the long way, 128 longs */
- long cnt, zero = 0;
-
- writeSize = 4;
- for(cnt = 0; cnt < 128; cnt++)
- {
- err = FSWrite(refNum, &writeSize, &zero);
- if(err != noErr)
- break;
- }
- }
-
- /* Try the quick and dirty method, allocating the pict in app RAM (doesn't
- work unless there's a large, contiguous pile of spare memory */
- gPictHandle = WorldToPict(world);
- if(gPictHandle != nil)
- {
- /* How about that, it worked */
- writeSize = GetHandleSize(gPictHandle);
- err = FSWrite(refNum, &writeSize, *gPictHandle);
- KillPicture(gPictHandle);
- gPictHandle = nil;
- }
- else
- {
- /* Do it the slower, safer way */
-
- /* Set the marker to the beginning of the pict data, skipping over the
- picSize and picFrame fields (those'll be updated when we're done. Be sure the
- file is big enough before doing so. */
- if(err == noErr)
- {
- err = SetEOF(refNum, kPICTHeaderSize + sizeof(Picture));
- if(err == noErr)
- err = SetFPos(refNum, fsFromStart, kPICTHeaderSize + sizeof(Picture));
- }
-
- /* OK, the file is ready to accept the PICT data. Now we need to
- set up the QDProcs in our GWorld so that it will get written. */
- if(err == noErr)
- {
- /* Move to the GWorld, save the old procs */
- SetGWorld(world, nil);
- oldProcs = world->grafProcs;
-
- /* Initialize the new procs with default values, then insert our custom
- putPic Proc and install in the world */
- SetStdCProcs(&newProcs);
- newProcs.putPicProc = PictWriter;
- world->grafProcs = &newProcs;
-
- /* Now set up the globals that PictWriter needs */
- gPictError = noErr;
- gPictSize = sizeof(Picture); /* Starting size of the pict is just the
- size of the picSize and picFrame fields */
- gPictFileRef = refNum;
- gPictHandle = nil; /* This is important! OpenPicture calls PictWriter
- BEFORE the handle is allocated, so it needs to
- be nil going in. */
-
- /* OK, finally we get to do the dirty. Open a picture, copybits the world
- to itself, and close the picture */
- if(LockWorld(world))
- {
- ForeColor(blackColor);
- gPictHandle = OpenPicture(&world->portRect);
- CopyBits(*GetGWorldPixMap(world), *GetGWorldPixMap(world),
- &world->portRect, &world->portRect, srcCopy, nil);
- ClosePicture();
- UnlockWorld(world);
- err = noErr;
- }
- else
- /* Couldn't lock the world's pixels, so post a generic error */
- err = -1;
-
- /* Check both possible errors */
- if(gPictError == noErr && err == noErr)
- {
- /* Hot Dawg! Got our pict data out. But we're not done yet. Now we need to
- write the (now correct) header info (not the FILE header, but the picSize
- and picFrame fields of the pict data). */
- err = SetFPos(refNum, fsFromStart, kPICTHeaderSize);
- if(err == noErr)
- {
- writeSize = sizeof(Picture);
- FSWrite(refNum, &writeSize, *gPictHandle);
- }
- }
-
- /* Restore the GrafProcs and kill the picture */
- world->grafProcs = oldProcs;
- KillPicture(gPictHandle);
- gPictHandle = nil;
- SetGWorld(oldport, olddev);
- }
- }
-
- /* Close the file. If there were errors, the file is deleted by the caller, who
- created it in the first place */
- FSClose(refNum);
- }
- return err;
- }
-
- /* Prints the specified world. This is a plain vanilla print loop. */
- void Print(GWorldPtr world)
- {
- short err;
- CGrafPtr oldport;
- GDHandle olddev;
-
- GetGWorld(&oldport, &olddev);
- MoveHHi((Handle)gPrintRecHandle);
- HLock((Handle)gPrintRecHandle);
- PrOpen(); /* Open Print Mgr */
- err = PrError(); /* Check for errors */
- if(err == noErr)
- {
- Boolean OKclicked;
-
- OKclicked = PrJobDialog(gPrintRecHandle); /* Run print dialog */
- err = PrError(); /* Check for errors */
- if(err == noErr && OKclicked)
- {
- short numCopies, copy;
- DialogPtr dptr;
-
- /* Put up the "To cancel printing..." dialog */
- dptr = GetNewDialog(kPrintingNowDlogID, nil, (Ptr)(-1));
- if(dptr != nil)
- DrawDialog(dptr);
-
- /* Only print one page, but possibly lots 'o copies */
- (*gPrintRecHandle)->prJob.iFstPage = 1;
- (*gPrintRecHandle)->prJob.iLstPage = 1;
- numCopies = (*gPrintRecHandle)->prJob.iCopies;
- for(copy = 1; copy <= numCopies; copy++)
- {
- TPPrPort printPort;
-
- printPort = PrOpenDoc(gPrintRecHandle, nil, nil);
- err = PrError();
- if(err == noErr)
- {
- PrOpenPage(printPort, nil);
- err = PrError();
- if(err == noErr)
- {
- Rect pageRect, dstRect;
- Point ctr;
-
- dstRect = world->portRect;
- pageRect = (**gPrintRecHandle).prInfo.rPage;
- ctr = Center(&pageRect);
- CenterRect(&dstRect, &ctr);
- if(LockWorld(world))
- {
- CopyBits(*GetGWorldPixMap(world), &printPort->gPort.portBits,
- &world->portRect, &dstRect, srcCopy, nil);
- UnlockWorld(world);
- }
- }
- PrClosePage(printPort);
-
- }
- PrCloseDoc(printPort);
- } /* copies loop */
- if(dptr != nil)
- DisposDialog(dptr);
-
- if((**gPrintRecHandle).prJob.bJDocLoop == bSpoolLoop && PrError() == noErr)
- {
- TPrStatus dummy;
-
- PrPicFile(gPrintRecHandle, nil, nil, nil, &dummy);
- }
- }
- }
- else
- DoErrorAlert(kNoPrinterStr, 0);
-
- PrClose();
- SetGWorld(oldport, olddev);
- HUnlock((Handle)gPrintRecHandle);
- }
-
-
- /******************************************************************
-
- Filter routines
-
- *******************************************************************/
-
- void BuildFilterMenu(MenuHandle menu)
- {
- /* Piece 'o cake, this */
- AddResMenu(menu, 'FLTR');
- }
-
- short CallFilter(GWorldPtr world, Handle theFilter)
- {
- short result;
- FilterFunc filter;
-
- if(theFilter == nil)
- return noErr; /* Don't do anything */
-
- MoveHHi(theFilter);
- HLock(theFilter);
- filter = (FilterFunc)(*theFilter);
- filter = StripAddress(filter); /* Just in case the filter swaps modes */
- result = filter(world);
- HUnlock(theFilter);
- return result;
- }
-
- /******************************************************************
-
- Brush routines
-
- *******************************************************************/
-
- void BuildBrushMenu(MenuHandle menu)
- {
- /* Piece 'o cake, this */
- AddResMenu(menu, 'BRSH');
- }
-
-
- short CallBrush(short msg, BrushParams *params, Handle theBrush)
- {
- short result;
- BrushFunc brush;
-
- if(theBrush == nil)
- return noErr; /* Don't do anything */
-
- MoveHHi(theBrush);
- HLock(theBrush);
- brush = (BrushFunc)(*theBrush);
- brush = StripAddress(brush); /* Just in case the brush swaps modes */
- result = brush(msg, params);
- HUnlock(theBrush);
- return result;
- }
-
-
- /* This routine gets the new brush, kills the old one, and adjusts the menus */
- OSErr SetCurrentBrush(short brushNum)
- {
- Str255 brushName;
- Handle newBrush;
- BrushParams tempStuff;
- OSErr rslt = -1; /* generic error */
-
- /* If the brushNum is the same as the current brush, just restart the brush. */
- if(brushNum == gCurrentBrushNum)
- {
- CallBrush(kStopBrush, &gBrushStuff, gCurrentBrushHandle);
- CallBrush(kStartBrush, &gBrushStuff, gCurrentBrushHandle);
- rslt = noErr;
- }
- else /* really a new brush */
- {
- /* Get the name of the brush */
- GetItem(gPaintMenuHandles[kBrushMenu], brushNum, brushName);
-
- /* Load the brush */
- newBrush = GetNamedResource('BRSH', brushName);
- if(ResError() == noErr && newBrush != nil)
- {
- /* Start it up */
- tempStuff = gBrushStuff; /* copy the BrushParams */
- rslt = CallBrush(kStartBrush, &tempStuff, newBrush);
- if(rslt >= 0)
- {
- /* Looks good, Kill old brush */
- if(gCurrentBrushHandle != nil)
- {
- CallBrush(kStopBrush, &gBrushStuff, gCurrentBrushHandle);
- ReleaseResource(gCurrentBrushHandle);
- gBrushStuff.storage = (long)nil;
- }
-
- /* make tempStuff the real thing */
- gBrushStuff = tempStuff;
-
- /* Adjust Menus */
- CheckItem(gPaintMenuHandles[kBrushMenu], gCurrentBrushNum, false);
- CheckItem(gPaintMenuHandles[kBrushMenu], brushNum, true);
-
- if(rslt & kConfigMask) /* A configurable brush, Enable the menu item */
- EnableItem(gPaintMenuHandles[kBrushMenu], iConfigureBrush);
- else
- DisableItem(gPaintMenuHandles[kBrushMenu], iConfigureBrush);
-
- /* Set the globals and rslt */
- gCurrentBrushHandle = newBrush;
- gCurrentBrushNum = brushNum;
- rslt = noErr;
- }
- }
- else
- DoErrorAlert(kNoBrushStr, 0);
- }
- return rslt;
- }
-
-